package com.eascs.admin.o2o.loan.service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSONObject;
import com.eascs.account.account.AccountEntity;
import com.eascs.account.api.IAccountService;
import com.eascs.account.api.IFeeService;
import com.eascs.account.api.constants.enums.SourceType;
import com.eascs.account.api.constants.enums.TradeType;
import com.eascs.account.api.vo.TradeDetailVO;
import com.eascs.account.api.vo.TradeParamsVO;
import com.eascs.admin.common.utils.AccountConstants;
import com.eascs.admin.o2o.internal.dao.LoanapplyExpandDao;
import com.eascs.admin.o2o.internal.entity.LoanapplyExpand;
import com.eascs.admin.o2o.internal.service.LoanapplyExpandService;
import com.eascs.admin.o2o.internal.util.BaseUserUtil;
import com.eascs.admin.o2o.internal.util.StatusContexts;
import com.eascs.admin.o2o.loan.entity.O2oLoanapplyEntity;
import com.eascs.admin.o2o.loanAccount.entity.AccountLog;
import com.eascs.admin.o2o.loanAccount.entity.O2oLoanapplyAccountEntity;
import com.eascs.admin.o2o.loanAccount.service.IAccountLogService;
import com.eascs.admin.o2o.loanAccount.serviceimpl.O2oLoanapplyAccountImpl;
import com.eascs.admin.o2o.submitted.service.IO2oChargeSituationService;
import com.eascs.app.log.Logger;
import com.eascs.app.log.LoggerFactory;
import com.eascs.common.util.StringUtil;
import com.eascs.common.util.UuidUtil;
import com.eascs.crm.common.custnew.entity.CustomerEntity;
import com.eascs.crm.common.custnew.service.CustomerService;
import com.eascs.workflow.common.vo.ModelResult;

@Service
public class O2oChargeSituationService implements IO2oChargeSituationService {
	private static Logger logger = LoggerFactory.getLogger(O2oChargeSituationService.class);
	@Autowired
	private O2oLoanapplyService o2oLoanapplyService;
	@Reference
	private IAccountService iAccountService;
	@Reference
	private CustomerService customerService;
	@Autowired
	private LoanapplyExpandService loanapplyExpandService;
	@Autowired
	private LoanapplyExpandDao loanapplyExpandDao;
	@Autowired
	private BaseUserUtil userUtils;
	@Reference
	private IFeeService iFeeService;
	@Autowired
	private O2oLoanapplyAccountImpl io2oLoanapplyAccountService;
	@Autowired
	private ChargingService chargingService;
	@Reference
	private IAccountLogService iAccountLogService;

	/**
	 * 根据贷款ID查询借款人可用金额
	 * 
	 * @param loanapplyNo
	 * @return
	 */
	public BigDecimal getFreezeBalance(String loanapplyNo) {
		logger.info("开始查询贷款信息");
		O2oLoanapplyEntity loanapplyEntity = o2oLoanapplyService.findById(loanapplyNo);
		logger.info("查询贷款信息:{}", loanapplyEntity);
		logger.info("访问CustomerService接口开始");
		CustomerEntity customerEntity = customerService.queryCustomerEntityByCustomerId(loanapplyEntity.getLoanId());
		logger.info("访问CustomerService接口结束，结果：{}", customerEntity);
		if (StringUtil.isNotBlank(customerEntity.getAccountId())) {
			logger.info("访问IAccountService接口开始");
			ModelResult<List<AccountEntity>> model = iAccountService.queryIndividualAccount(customerEntity.getAccountId());
			if (model.isSuccess()) {
				logger.info("访问IAccountService接口结束，返回状态：成功");
				List<AccountEntity> entities = model.getModel();
				logger.info("访问IAccountService接口结果数据：{}，条数：", entities, entities.size());
				for (AccountEntity accountEntity : entities) {
					if ("21".equals(accountEntity.getAccountTypeCode())) {// 个人可用金额账户类型
						logger.info("访问IAccountService接口结果数据账号为可用金额账号：{}", accountEntity.getAccountTypeCode());
						return accountEntity.getBalance();
					}
				}
			}
			logger.info("访问IAccountService接口结束，返回状态：失败");
		}

		return new BigDecimal(0);
	}

	/**
	 * 根据贷款ID查询借款人可用账号
	 * 
	 * @param loanapplyNo
	 * @return
	 */
	public CustomerEntity getCustomerEntity(String loanapplyNo) {
		logger.info("开始查询贷款信息");
		O2oLoanapplyEntity loanapplyEntity = o2oLoanapplyService.findById(loanapplyNo);
		logger.info("查询贷款信息:{}", loanapplyEntity);
		logger.info("访问CustomerService接口开始");
		CustomerEntity customerEntity = customerService.queryCustomerEntityByCustomerId(loanapplyEntity.getLoanId());
		logger.info("访问CustomerService接口结束，结果：{}", customerEntity);
		return customerEntity;
	}

	/**
	 * 根据借款人ID查询可用金额
	 * 
	 * @param loanapplyNo
	 * @return
	 */
	public BigDecimal getFreezeBalanceByLoanId(String loanId) {
		logger.info("访问CustomerService接口开始");
		CustomerEntity customerEntity = customerService.queryCustomerEntityByCustomerId(loanId);
		logger.info("访问CustomerService接口结束，结果：{}", customerEntity);
		if (null != customerEntity && StringUtil.isNotBlank(customerEntity.getAccountId())) {
			logger.info("访问IAccountService接口开始");
			ModelResult<List<AccountEntity>> model = iAccountService.queryIndividualAccount(customerEntity.getAccountId());
			if (model.isSuccess()) {
				logger.info("访问IAccountService接口结束，返回状态：成功");
				List<AccountEntity> entities = model.getModel();
				logger.info("访问IAccountService接口结果数据：{}，条数：", JSONObject.toJSONString(entities), entities.size());
				for (AccountEntity accountEntity : entities) {
					if ("21".equals(accountEntity.getAccountTypeCode())) {// 个人可用金额账户类型
						logger.info("访问IAccountService接口结果数据账号为可用金额账号：{}", accountEntity.getAccountTypeCode());
						return accountEntity.getBalance();
					}
				}
			}
			logger.info("访问IAccountService接口结束，返回状态：失败,【信息：{}】", model.getErrMsg());
		}

		return new BigDecimal(0);
	}

	/**
	 * 根据用户ID或贷款单ID查询可用账户及余额,冻结账户及余额
	 * 
	 * @param loanId
	 *            用户ID
	 * @param loanapplyNo
	 *            贷款单ID
	 * @param type
	 *            账户类型21为可用，22为冻结
	 * @return
	 */
	public AccountEntity queryByLoanId(String loanId, String loanapplyNo, String type) {
		O2oLoanapplyEntity loanapplyEntity = null;
		CustomerEntity customerEntity = null;
		if (StringUtil.isNotBlank(loanapplyNo) && StringUtil.isBlank(loanId)) {
			logger.info("开始查询贷款信息");
			loanapplyEntity = o2oLoanapplyService.findById(loanapplyNo);
			logger.info("查询贷款信息:{}", loanapplyEntity);
			logger.info("访问CustomerService接口开始");
			customerEntity = customerService.queryCustomerEntityByCustomerId(loanapplyEntity.getLoanId());
			logger.info("访问CustomerService接口结束，结果：{}", customerEntity);
		} else if (StringUtil.isNotBlank(loanId)) {
			logger.info("访问CustomerService接口开始");
			customerEntity = customerService.queryCustomerEntityByCustomerId(loanId);
			logger.info("访问CustomerService接口结束，结果：{}", customerEntity);
		}
		if (StringUtil.isNotBlank(customerEntity.getAccountId())) {
			logger.info("访问IAccountService接口开始");
			ModelResult<List<AccountEntity>> model = iAccountService.queryIndividualAccount(customerEntity.getAccountId());
			if (model.isSuccess()) {
				logger.info("访问IAccountService接口结束，返回状态：成功");
				List<AccountEntity> entities = model.getModel();
				logger.info("访问IAccountService接口结果数据：{}，条数：", JSONObject.toJSONString(entities), entities.size());
				for (AccountEntity accountEntity : entities) {
					if (type.equals(accountEntity.getAccountTypeCode())) {// 个人可用/冻结金额账户类型
						logger.info("访问IAccountService接口结果数据账号为可用金额账号：{}", accountEntity);
						return accountEntity;
					}
				}
			}
			logger.info("访问IAccountService接口结束，返回状态：失败,【信息：{}】", model.getErrMsg());
		}
		return null;
	}

	public AccountEntity queryLoanAccount(String loanapplyNo, String type) {
		AccountEntity entity = new AccountEntity();
		logger.info("loanapplyNo:{}", loanapplyNo);
		O2oLoanapplyAccountEntity loanapplyAccountEntity = io2oLoanapplyAccountService.getEntityByLoanapplyNo(loanapplyNo);
		logger.info("查询贷款信息:{}", loanapplyAccountEntity);
		if (loanapplyAccountEntity != null && StringUtil.isNotBlank(loanapplyAccountEntity.getAccountNo())) {
			logger.info("访问IAccountService接口开始");
			ModelResult<List<AccountEntity>> model = iAccountService.queryIndividualAccount(loanapplyAccountEntity.getAccountNo());
			if (model.isSuccess()) {
				logger.info("访问IAccountService接口结束，返回状态：成功");
				List<AccountEntity> entities = model.getModel();
				logger.info("访问IAccountService接口结果数据：{}，条数：", JSONObject.toJSONString(entities), entities.size());
				for (AccountEntity accountEntity : entities) {
					if (type.equals(accountEntity.getAccountTypeCode())) {// 保证金、风险补偿金、管理费
						logger.info("访问IAccountService接口结果数据账号：{}", accountEntity.getAccount());
						logger.info("访问IAccountService接口结果数据类型：{}", accountEntity.getAccountTypeName());
						return accountEntity;
					}
				}
			}
			logger.info("访问IAccountService接口结束，返回状态：失败,【信息：{}】", model.getErrMsg());
		}
		return entity;
	}

	/**
	 * 计算应收保证金、管理费、风险补偿金
	 * 
	 * @return
	 */
	public LoanapplyExpand queryExpandByLoanapplyNo(String loanapplyNo) {
		logger.info("开始查询贷款信息");
		// O2oLoanapplyEntity loanapplyEntity =
		// o2oLoanapplyService.findById(loanapplyNo);
		LoanapplyExpand loanapplyExpand = loanapplyExpandService.queryLoanapplyNo(loanapplyNo);
		logger.info("查询贷款信息:{}", loanapplyExpand);
		/*
		 * loanapplyExpand.setLoanapply_no(loanapplyNo); BigDecimal year = new
		 * BigDecimal(12); // 保证金=贷款金额*费率
		 * loanapplyExpand.setRecDeposite(loanapplyEntity
		 * .getEaMount().multiply(loanapplyEntity.getDepositrate())); //
		 * 管理费=(贷款金额*年化费率)/12*贷款月数 BigDecimal loanTerm = new
		 * BigDecimal(loanapplyEntity.getLoanTerm()); BigDecimal term = new
		 * BigDecimal(6); BigDecimal term1 = new BigDecimal(12); BigDecimal
		 * manger =
		 * (loanapplyEntity.getEaMount()).multiply((loanapplyEntity.getManagefeerate
		 * ())); // 风险保证金 不足半年按半年收取，超过半年按一年收取；管理费 不足半年，按半年收取，半年以上，按实际收取 if
		 * (loanTerm.compareTo(term) == -1) {
		 * loanapplyExpand.setRecManger((manger.multiply(term).divide(year, 2,
		 * BigDecimal.ROUND_HALF_UP))); // 风险补偿金=(贷款金额*年化费率)/12*贷款月数
		 * loanapplyExpand
		 * .setRecRisk(((loanapplyEntity.getEaMount()).multiply(loanapplyEntity
		 * .getRisk()).multiply(term).divide(year, 2,
		 * BigDecimal.ROUND_HALF_UP))); } else if (loanTerm.compareTo(term) ==
		 * 0) {
		 * loanapplyExpand.setRecManger((manger.multiply(loanTerm).divide(year,
		 * 2, BigDecimal.ROUND_HALF_UP)));
		 * loanapplyExpand.setRecRisk(((loanapplyEntity
		 * .getEaMount()).multiply(loanapplyEntity
		 * .getRisk()).multiply(loanTerm).divide(year, 2,
		 * BigDecimal.ROUND_HALF_UP))); } else {
		 * loanapplyExpand.setRecManger((manger.multiply(loanTerm).divide(year,
		 * 2, BigDecimal.ROUND_HALF_UP)));
		 * loanapplyExpand.setRecRisk(((loanapplyEntity
		 * .getEaMount()).multiply(loanapplyEntity
		 * .getRisk()).multiply(term1).divide(year, 2,
		 * BigDecimal.ROUND_HALF_UP))); }
		 */
		return loanapplyExpand;
	}

	/**
	 * 保存或更新保证金管理费
	 * 
	 * @param expand
	 */
	public void updateLoanapplyExpand(LoanapplyExpand expand, String status) {
		if (StringUtil.isNotBlank(expand.getId())) {
			expand.setBillStatus(status);
			if (StatusContexts.BZJ_STATUS_CLO.equals(status)) {
				expand.setRedDeposite(expand.getRecDeposite());
				expand.setRedManger(expand.getRecManger());
				expand.setRedRisk(expand.getRecRisk());
				expand.setRetaDeposite(BigDecimal.ZERO);
				expand.setRetaManage(BigDecimal.ZERO);
				expand.setRetaRisk(BigDecimal.ZERO);
			} else {
				expand.setRetaDeposite(BigDecimal.ZERO);
				expand.setRetaManage(BigDecimal.ZERO);
				expand.setRetaRisk(BigDecimal.ZERO);
				expand.setRedDeposite(BigDecimal.ZERO);
				expand.setRedManger(BigDecimal.ZERO);
				expand.setRedRisk(BigDecimal.ZERO);
			}
			loanapplyExpandDao.updateById(expand);
		} else {
			O2oLoanapplyEntity loanapplyEntity = o2oLoanapplyService.findById(expand.getLoanapply_no());
			expand.setRedDeposite(expand.getRecDeposite());
			expand.setRedManger(expand.getRecManger());
			expand.setRedRisk(expand.getRecRisk());
			expand.setPaymentType(loanapplyEntity.getPaymentType());
			expand.setBankLoanName(loanapplyEntity.getBankLoanName());
			expand.setGeneralRate(loanapplyEntity.getGeneralRate());
			expand.setBillStatus(status);
			expand.setBillCode(loanapplyEntity.getBillCode());
			expand.setRisk(loanapplyEntity.getRisk());
			expand.setUpdator(userUtils.getUpdateOr());
			expand.setCreator(userUtils.getCreateOr());
			expand.setCreat_time(new Date());
			expand.setUpdateTime(new Date());
			expand.setDelFlag(StatusContexts.O2O_NO);
			expand.setRemark(loanapplyEntity.getRemark());
			expand.setDepositrate(loanapplyEntity.getDepositrate());
			expand.setManagefeerate(loanapplyEntity.getManagefeerate());
			expand.setRisk(loanapplyEntity.getRisk());
			loanapplyExpandDao.insert(expand);
		}
	}

	/**
	 * 扣费、退费(运维直接扣费、退费)
	 * 
	 * @param expand
	 * @param type
	 * @return
	 */
	public String ChargingKFTF(LoanapplyExpand expand, String type) {
		return chargingService.ChargingKFTF(expand, type);
	}

	/**
	 * 扣费、退费(银行申报审节点扣费)
	 * 
	 * @param expand
	 * @param type
	 * @return
	 */
	public String Charging(LoanapplyExpand expand, String type) {
		return chargingService.Charging(expand, type);
	}

	/**
	 * 银行收费收入公司账户
	 * 
	 * @param expand
	 * @return
	 */
	public String transfer(LoanapplyExpand expand) {
		O2oLoanapplyAccountEntity loanapplyAccountEntity = io2oLoanapplyAccountService.getEntityByLoanapplyNo(expand.getLoanapply_no());
		if (null == loanapplyAccountEntity) {
			return "贷款单账户未开户，请联系运维同事";
		} else if (StringUtil.isBlank(loanapplyAccountEntity.getAccountNo())) {
			return "贷款单账户未开户，请稍后重试";
		}
		TradeParamsVO paramsVO = new TradeParamsVO();
		List<TradeDetailVO> detailsVO = new ArrayList<TradeDetailVO>();
		TradeDetailVO recManger = new TradeDetailVO();// 封装保证金管理费风险补偿金数据
		TradeDetailVO recRisk = new TradeDetailVO();// 封装保证金管理费风险补偿金数据
		O2oLoanapplyEntity loanapplyEntity = o2oLoanapplyService.findById(expand.getLoanapply_no());
		recManger.setRollInAccount(loanapplyAccountEntity.getAccountNo());// 转出账户
		recManger.setRollOutAccount("");// 转入账户
		recManger.setAmount(expand.getRedManger());
		recManger.setRemark("管理费转入公司账户，单号：" + loanapplyEntity.getBillCode());
		recRisk.setRollInAccount(loanapplyAccountEntity.getAccountNo());// 转出账户
		recRisk.setRollOutAccount("");// 转入账户
		recRisk.setAmount(expand.getRedRisk());
		recRisk.setRemark("风险补偿金转入公司账户，单号：" + loanapplyEntity.getBillCode());

		recManger.setTradeType(TradeType.ISTRATION_IN_CM);
		recManger.setTradeBankcardNoIn("");// 本方交易银行卡号
		recManger.setTradeBankcardNoOut("");// 对方交易银行卡号
		recManger.setTradeDate(new Date());
		detailsVO.add(recManger);

		recRisk.setTradeType(TradeType.COMPENSATION_IN_CM);
		recRisk.setTradeBankcardNoIn("");// 本方交易银行卡号
		recRisk.setTradeBankcardNoOut("");// 对方交易银行卡号
		recRisk.setTradeDate(new Date());
		detailsVO.add(recRisk);

		AccountLog accountLog = new AccountLog();
		accountLog.setStartTime(new Date());
		accountLog.setId(UuidUtil.generateShortUuid());
		String bizType = AccountConstants.ACCOUNT_ZR;
		paramsVO.setUniqueId(expand.getId());
		paramsVO.setBizId(accountLog.getId());// 业务ID取临时表ID，以便判断是否执行多次
		paramsVO.setBizType(bizType);
		paramsVO.setDetails(detailsVO);
		paramsVO.setRemark("贷款单账户划到公司账户，单号：" + loanapplyEntity.getBillCode());
		paramsVO.setRequestId(accountLog.getId());
		paramsVO.setSource(SourceType.WEB);

		ModelResult<String> result = null;
		String resultStr = "";
		try {
			logger.info("非国安村镇银行调用扣费接口开始，参数：【{}】", JSONObject.toJSONString(paramsVO));
			result = iFeeService.fee(paramsVO);
			logger.info("非国安村镇银行调用扣费接口结束，成功与否：{},【信息：{}】", result.isSuccess(), result.getErrMsg());
			if (result.isSuccess()) {// 如果调用成功
//				accountLog.setStatus(String.valueOf(result.isSuccess()));
//				accountLog.setEndTime(new Date());
//				accountLog.setRequestid(accountLog.getId());
//				accountLog.setRequestPs(JSONObject.toJSONString(paramsVO));
//				accountLog.setResponsePs(JSONObject.toJSONString(result));
//				accountLog.setClassname(this.getClass().getName());
//				accountLog.setLogType(bizType);
//				accountLog.setLoanapplyNo(expand.getLoanapply_no());
//				accountLog.setMethodname(Thread.currentThread().getStackTrace()[1].getMethodName());
//				logger.info("非国安村镇银行调用service账号接口开始");
//				iAccountLogService.add(accountLog);
//				logger.info("非国安村镇银行调用service账号接口结束");
				resultStr = "SUCCESS";
			} else {
				resultStr = result.getErrMsg() + "——扣费失败，单号：" + loanapplyEntity.getBillCode();
			}
		} catch (Exception e) {
			logger.error("非国安村镇银行调用扣费接口失败，失败信息为：{}", e.getMessage());
			resultStr = "扣费失败，单号：" + loanapplyEntity.getBillCode();
		} finally {
			if (result.isSuccess()) {
				accountLog.setStatus(String.valueOf(result.isSuccess()));
			} else {
				accountLog.setStatus("false");
			}
			accountLog.setEndTime(new Date());
			accountLog.setRequestid(accountLog.getId());
			accountLog.setRequestPs(JSONObject.toJSONString(paramsVO));
			accountLog.setResponsePs(JSONObject.toJSONString(result));
			accountLog.setClassname(this.getClass().getName());
			accountLog.setLogType(bizType);
			accountLog.setLoanapplyNo(expand.getLoanapply_no());
			accountLog.setMethodname(Thread.currentThread().getStackTrace()[1].getMethodName());
			logger.info("调用service账号接口开始");
			iAccountLogService.add(accountLog);
			logger.info("调用service账号接口结束");
		}
		return resultStr;
	}

	@Override
	public com.eascs.admin.common.vo.ModelResult<Boolean> queryListCharge() {
		logger.info("定时器启动调用接口");
		com.eascs.admin.common.vo.ModelResult<Boolean> result = new com.eascs.admin.common.vo.ModelResult<Boolean>();
		try {
			String sql = "select oblt.loanapply_no from o2o_bank_loan_data_timer oblt where  oblt.is_debit='N' and oblt.flow_status='Y' limit 0,50";
			List<String> collectIds = loanapplyExpandDao.findSimpleObjectList(sql, String.class);
			if (null != collectIds && collectIds.size() > 0) {
				logger.info("query list:【{}】", JSONObject.toJSONString(collectIds));
				String resultStr = "";
				for (String id : collectIds) {
					if (id.equals("")) {
						break;
					}
					LoanapplyExpand expand = loanapplyExpandDao.queryLoanapplyNo(id);
					if (null == expand.getRedManger()) {
						expand.setRedManger(BigDecimal.ZERO);
					}
					if (null == expand.getRedRisk()) {
						expand.setRedRisk(BigDecimal.ZERO);
					}
					if (null == expand.getRetaManage()) {
						expand.setRetaManage(BigDecimal.ZERO);
					}
					if (null == expand.getRetaRisk()) {
						expand.setRetaRisk(BigDecimal.ZERO);
					}
					BigDecimal redManger = new BigDecimal(0);
					BigDecimal redRisk = new BigDecimal(0);
					redManger = expand.getRedManger().subtract(expand.getRetaManage());
					redRisk = expand.getRedRisk().subtract(expand.getRetaRisk());
					if (redManger.compareTo(BigDecimal.ZERO) > 0 && redRisk.compareTo(BigDecimal.ZERO) > 0) {
						expand.setRedManger(redManger);
						expand.setRedRisk(redRisk);
						logger.info("query LoanapplyExpand:【{}】", JSONObject.toJSONString(expand));
						resultStr = transfer(expand);
						logger.info("result str:【{}】", resultStr);
						if ("SUCCESS".equals(resultStr)) {
							String updateSql = "update o2o_bank_loan_data_timer set is_debit='Y' where loanapply_no=?";
							loanapplyExpandDao.execute(updateSql, id);
						}
					}
				}
				result.withModel(true);
				result.setErrMsg(resultStr);
				return result;
			}
		} catch (Exception e) {
			logger.error("定时器调用贷款贷账户划到公司账户异常，信息：【{}】", e.getMessage());
			result.withError("ERROR", "定时器调用贷款贷账户划到公司账户异常，");
			return result;
		}
		result.withError("FALSE", "导入放款信息为空，无法放款");
		return result;
	}

}
